<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>本地Git可视化工具</title>
  <script src="https://cdn.tailwindcss.com"></script>
  <link href="https://cdn.jsdelivr.net/npm/font-awesome@4.7.0/css/font-awesome.min.css" rel="stylesheet">
</head>
<body class="bg-gray-100 min-h-screen">
  <div class="container mx-auto p-4 max-w-6xl">
    <header class="mb-6">
      <h1 class="text-3xl font-bold text-gray-800">本地Git可视化工具</h1>
    </header>

    <div class="grid grid-cols-1 lg:grid-cols-4 gap-6">
      <!-- 左侧：仓库设置 -->
      <div class="bg-white rounded-lg shadow p-4">
        <h2 class="text-xl font-semibold mb-4 flex items-center">
          <i class="fa fa-folder-open text-blue-500 mr-2"></i>仓库设置
        </h2>
        <div class="mb-4">
          <label class="block text-gray-700 mb-2">仓库路径</label>
          <input type="text" id="repoPath" class="w-full p-2 border border-gray-300 rounded" 
                 placeholder="例如: /Users/yourname/project">
          <button id="initRepo" class="mt-2 bg-green-500 text-white p-2 rounded hover:bg-green-600">
            <i class="fa fa-plus mr-1"></i>初始化仓库
          </button>
        </div>
        <div id="repoStatus" class="text-sm text-gray-600"></div>
      </div>

      <!-- 中间左侧：文件状态 -->
      <div class="bg-white rounded-lg shadow p-4">
        <h2 class="text-xl font-semibold mb-4 flex items-center">
          <i class="fa fa-file-text text-purple-500 mr-2"></i>文件状态
        </h2>
        <button id="refreshStatus" class="mb-4 bg-blue-500 text-white p-2 rounded hover:bg-blue-600">
          <i class="fa fa-refresh mr-1"></i>刷新状态
        </button>
        <div id="fileStatus" class="space-y-2 max-h-64 overflow-y-auto"></div>
        <div class="mt-4 space-y-2">
          <button id="stageAll" class="w-full bg-yellow-500 text-white p-2 rounded hover:bg-yellow-600">
            <i class="fa fa-plus-square mr-1"></i>暂存所有文件
          </button>
          <button id="resetAll" class="w-full bg-red-500 text-white p-2 rounded hover:bg-red-600">
            <i class="fa fa-minus-square mr-1"></i>取消暂存所有文件
          </button>
        </div>
      </div>

      <!-- 中间右侧：分支管理 -->
      <div class="bg-white rounded-lg shadow p-4">
        <h2 class="text-xl font-semibold mb-4 flex items-center">
          <i class="fa fa-code-fork text-orange-500 mr-2"></i>分支管理
        </h2>
        <button id="refreshBranches" class="mb-4 bg-orange-500 text-white p-2 rounded hover:bg-orange-600">
          <i class="fa fa-refresh mr-1"></i>刷新分支
        </button>
        <div id="currentBranch" class="mb-3 p-2 bg-blue-100 rounded text-sm font-medium"></div>
        <div id="branchList" class="space-y-2 max-h-64 overflow-y-auto mb-4"></div>
        <div class="space-y-2">
          <div class="flex space-x-2">
            <input type="text" id="newBranchName" class="flex-1 p-2 border border-gray-300 rounded text-sm" 
                   placeholder="新分支名称">
            <button id="createBranch" class="bg-green-500 text-white p-2 rounded hover:bg-green-600 text-sm">
              <i class="fa fa-plus"></i>
            </button>
          </div>
        </div>
        
        <div class="mt-4 pt-4 border-t">
          <h3 class="text-lg font-medium mb-2 flex items-center">
            <i class="fa fa-cloud-upload text-blue-500 mr-2"></i>远程仓库
          </h3>
          <button id="refreshRemotes" class="mb-2 bg-blue-500 text-white p-1 rounded hover:bg-blue-600 text-sm">
            <i class="fa fa-refresh mr-1"></i>刷新远程
          </button>
          <div id="remoteList" class="space-y-1 mb-2 max-h-32 overflow-y-auto text-sm"></div>
          <div class="space-y-2 mb-2">
            <input type="text" id="remoteName" class="w-full p-2 border border-gray-300 rounded text-sm" 
                   placeholder="远程名称 (如: origin)">
            <input type="text" id="remoteUrl" class="w-full p-2 border border-gray-300 rounded text-sm" 
                   placeholder="远程URL (如: https://github.com/user/repo.git)">
            <button id="addRemote" class="w-full bg-blue-500 text-white p-2 rounded hover:bg-blue-600 text-sm">
              <i class="fa fa-plus mr-1"></i>添加远程仓库
            </button>
          </div>
          <button id="pushBranch" class="w-full bg-purple-500 text-white p-2 rounded hover:bg-purple-600">
            <i class="fa fa-cloud-upload mr-1"></i>推送当前分支
          </button>
        </div>
      </div>

      <!-- 右侧：提交区域 -->
      <div class="bg-white rounded-lg shadow p-4">
        <h2 class="text-xl font-semibold mb-4 flex items-center">
          <i class="fa fa-commit text-green-500 mr-2"></i>提交更改
        </h2>
        <div class="mb-4">
          <label class="block text-gray-700 mb-2">提交信息</label>
          <textarea id="commitMessage" rows="3" class="w-full p-2 border border-gray-300 rounded" 
                    placeholder="请输入提交信息..."></textarea>
          <button id="commitChanges" class="mt-2 bg-green-500 text-white p-2 rounded hover:bg-green-600">
            <i class="fa fa-check mr-1"></i>提交
          </button>
        </div>
        
        <h3 class="text-lg font-medium mt-6 mb-2">提交历史</h3>
        <div id="commitHistory" class="text-sm space-y-1 max-h-40 overflow-y-auto"></div>
        <button id="refreshHistory" class="mt-2 text-sm text-blue-500 hover:underline">
          <i class="fa fa-refresh mr-1"></i>刷新历史
        </button>
      </div>
    </div>
  </div>

  <script>
    // DOM元素
    const repoPathInput = document.getElementById('repoPath');
    const initRepoBtn = document.getElementById('initRepo');
    const repoStatusEl = document.getElementById('repoStatus');
    const refreshStatusBtn = document.getElementById('refreshStatus');
    const fileStatusEl = document.getElementById('fileStatus');
    const stageAllBtn = document.getElementById('stageAll');
    const resetAllBtn = document.getElementById('resetAll');
    const commitMessageInput = document.getElementById('commitMessage');
    const commitChangesBtn = document.getElementById('commitChanges');
    const commitHistoryEl = document.getElementById('commitHistory');
    const refreshHistoryBtn = document.getElementById('refreshHistory');
    
    // 分支管理相关DOM元素
    const refreshBranchesBtn = document.getElementById('refreshBranches');
    const currentBranchEl = document.getElementById('currentBranch');
    const branchListEl = document.getElementById('branchList');
    const newBranchNameInput = document.getElementById('newBranchName');
    const createBranchBtn = document.getElementById('createBranch');
    
    // 远程仓库管理相关DOM元素
    const refreshRemotesBtn = document.getElementById('refreshRemotes');
    const remoteListEl = document.getElementById('remoteList');
    const remoteNameInput = document.getElementById('remoteName');
    const remoteUrlInput = document.getElementById('remoteUrl');
    const addRemoteBtn = document.getElementById('addRemote');
    const pushBranchBtn = document.getElementById('pushBranch');

    // 辅助函数：显示消息
    const showMessage = (element, message, isError = false) => {
      element.textContent = message;
      element.className = isError ? 'text-red-500' : 'text-green-500';
    };

    // 初始化仓库
    initRepoBtn.addEventListener('click', async () => {
      const repoPath = repoPathInput.value.trim();
      if (!repoPath) return showMessage(repoStatusEl, '请输入仓库路径', true);
      
      try {
        const response = await fetch('/api/init', {
          method: 'POST',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify({ repoPath })
        });
        const data = await response.json();
        showMessage(repoStatusEl, data.message, !data.success);
        if (data.success) {
          refreshStatus();
          refreshBranches();
          refreshRemotes();
        }
      } catch (err) {
        showMessage(repoStatusEl, '初始化失败: ' + err.message, true);
      }
    });

    // 刷新文件状态
    const refreshStatus = async () => {
      const repoPath = repoPathInput.value.trim();
      if (!repoPath) return showMessage(fileStatusEl, '请先设置仓库路径', true);
      
      try {
        const response = await fetch('/api/status', {
          method: 'POST',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify({ repoPath })
        });
        const data = await response.json();
        
        if (data.success) {
          fileStatusEl.innerHTML = '';
          if (!data.status) {
            fileStatusEl.innerHTML = '<div class="text-gray-500">工作区干净，没有需要提交的更改</div>';
            return;
          }
          
          data.status.split('\n').forEach(line => {
            if (!line.trim()) return;
            const statusCode = line.substring(0, 2);
            const fileName = line.substring(3);
            const statusClass = statusCode.startsWith('??') ? 'text-yellow-500' : 
                               statusCode.startsWith(' M') ? 'text-orange-500' : 'text-blue-500';
            const statusText = statusCode.startsWith('??') ? '未跟踪' : 
                              statusCode.startsWith(' M') ? '已修改' : '已暂存';
            
            const fileEl = document.createElement('div');
            fileEl.className = `flex justify-between ${statusClass}`;
            fileEl.innerHTML = `
              <span>${fileName}</span>
              <span class="text-xs">${statusText}</span>
            `;
            fileStatusEl.appendChild(fileEl);
          });
        } else {
          showMessage(fileStatusEl, data.error, true);
        }
      } catch (err) {
        showMessage(fileStatusEl, '获取状态失败: ' + err.message, true);
      }
    };

    refreshStatusBtn.addEventListener('click', refreshStatus);

    // 暂存所有文件
    stageAllBtn.addEventListener('click', async () => {
      const repoPath = repoPathInput.value.trim();
      if (!repoPath) return showMessage(fileStatusEl, '请先设置仓库路径', true);
      
      try {
        const response = await fetch('/api/add', {
          method: 'POST',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify({ repoPath, files: ['.'] })
        });
        const data = await response.json();
        showMessage(fileStatusEl, data.message, !data.success);
        if (data.success) setTimeout(refreshStatus, 500);
      } catch (err) {
        showMessage(fileStatusEl, '暂存失败: ' + err.message, true);
      }
    });

    // 取消暂存所有文件
    resetAllBtn.addEventListener('click', async () => {
      const repoPath = repoPathInput.value.trim();
      if (!repoPath) return showMessage(fileStatusEl, '请先设置仓库路径', true);
      
      try {
        const response = await fetch('/api/reset', {
          method: 'POST',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify({ repoPath })
        });
        const data = await response.json();
        showMessage(fileStatusEl, data.success ? '已取消暂存所有文件' : data.error, !data.success);
        if (data.success) setTimeout(refreshStatus, 500);
      } catch (err) {
        showMessage(fileStatusEl, '取消暂存失败: ' + err.message, true);
      }
    });

    // 提交更改
    commitChangesBtn.addEventListener('click', async () => {
      const repoPath = repoPathInput.value.trim();
      const message = commitMessageInput.value.trim();
      
      if (!repoPath) return showMessage(repoStatusEl, '请输入仓库路径', true);
      if (!message) return showMessage(commitChangesBtn.parentElement, '请输入提交信息', true);
      
      try {
        const response = await fetch('/api/commit', {
          method: 'POST',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify({ repoPath, message })
        });
        const data = await response.json();
        showMessage(commitChangesBtn.parentElement, data.message, !data.success);
        if (data.success) {
          commitMessageInput.value = '';
          refreshStatus();
          refreshHistory();
          refreshBranches();
          refreshRemotes();
        }
      } catch (err) {
        showMessage(commitChangesBtn.parentElement, '提交失败: ' + err.message, true);
      }
    });

    // 刷新提交历史
    const refreshHistory = async () => {
      const repoPath = repoPathInput.value.trim();
      if (!repoPath) return showMessage(commitHistoryEl, '请先设置仓库路径', true);
      
      try {
        const response = await fetch('/api/log', {
          method: 'POST',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify({ repoPath })
        });
        const data = await response.json();
        
        if (data.success) {
          commitHistoryEl.innerHTML = '';
          if (!data.log) {
            commitHistoryEl.innerHTML = '<div class="text-gray-500">暂无提交历史</div>';
            return;
          }
          
          data.log.split('\n').forEach(line => {
            if (!line.trim()) return;
            const commitEl = document.createElement('div');
            commitEl.className = 'border-b border-gray-100 pb-1';
            commitEl.textContent = line;
            commitHistoryEl.appendChild(commitEl);
          });
        } else {
          showMessage(commitHistoryEl, data.error, true);
        }
      } catch (err) {
        showMessage(commitHistoryEl, '获取历史失败: ' + err.message, true);
      }
    };

    refreshHistoryBtn.addEventListener('click', refreshHistory);

    // 刷新分支列表
    const refreshBranches = async () => {
      const repoPath = repoPathInput.value.trim();
      if (!repoPath) return showMessage(branchListEl, '请先设置仓库路径', true);
      
      try {
        const response = await fetch('/api/branches', {
          method: 'POST',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify({ repoPath })
        });
        const data = await response.json();
        
        if (data.success) {
          branchListEl.innerHTML = '';
          currentBranchEl.textContent = '';
          
          if (data.branches && data.branches.length > 0) {
            // 显示当前分支
            const currentBranch = data.branches.find(branch => branch.current);
            if (currentBranch) {
              currentBranchEl.textContent = `当前分支: ${currentBranch.name}`;
            }
            
            // 显示分支列表
            data.branches.forEach(branch => {
              const branchEl = document.createElement('div');
              branchEl.className = 'flex justify-between items-center p-2 border rounded';
              
              if (branch.current) {
                branchEl.className += ' bg-blue-50 border-blue-300';
              }
              
              branchEl.innerHTML = `
                <span class="font-medium ${branch.current ? 'text-blue-700' : ''}">${branch.name}</span>
                <div class="space-x-1">
                  ${!branch.current ? `<button onclick="checkoutBranch('${branch.name}')" class="text-blue-500 hover:text-blue-700 text-sm" title="切换分支">
                    <i class="fa fa-code-fork"></i>
                  </button>` : ''}
                  ${!branch.current && branch.name !== 'main' && branch.name !== 'master' ? `<button onclick="deleteBranch('${branch.name}')" class="text-red-500 hover:text-red-700 text-sm" title="删除分支">
                    <i class="fa fa-trash"></i>
                  </button>` : ''}
                </div>
              `;
              
              branchListEl.appendChild(branchEl);
            });
          } else {
            branchListEl.innerHTML = '<div class="text-gray-500">没有分支</div>';
          }
        } else {
          showMessage(branchListEl, data.error, true);
          currentBranchEl.textContent = '';
        }
      } catch (err) {
        showMessage(branchListEl, '获取分支失败: ' + err.message, true);
        currentBranchEl.textContent = '';
      }
    };

    // 刷新分支按钮事件
    refreshBranchesBtn.addEventListener('click', refreshBranches);

    // 切换分支
    window.checkoutBranch = async (branchName) => {
      const repoPath = repoPathInput.value.trim();
      if (!repoPath) return showMessage(branchListEl, '请先设置仓库路径', true);
      
      try {
        const response = await fetch('/api/checkout', {
          method: 'POST',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify({ repoPath, branch: branchName })
        });
        const data = await response.json();
        
        if (data.success) {
          alert(`已切换到分支: ${branchName}`);
          refreshBranches();
          refreshStatus();
          refreshHistory();
        } else {
          alert(`切换分支失败: ${data.error}`);
        }
      } catch (err) {
        alert(`切换分支失败: ${err.message}`);
      }
    };

    // 创建新分支
    createBranchBtn.addEventListener('click', async () => {
      const repoPath = repoPathInput.value.trim();
      const branchName = newBranchNameInput.value.trim();
      
      if (!repoPath) return showMessage(branchListEl, '请先设置仓库路径', true);
      if (!branchName) return showMessage(branchListEl, '请输入分支名称', true);
      
      try {
        const response = await fetch('/api/create-branch', {
          method: 'POST',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify({ repoPath, branchName })
        });
        const data = await response.json();
        
        if (data.success) {
          alert(`分支创建成功: ${branchName}`);
          newBranchNameInput.value = '';
          refreshBranches();
        } else {
          alert(`创建分支失败: ${data.error}`);
        }
      } catch (err) {
        alert(`创建分支失败: ${err.message}`);
      }
    });

    // 删除分支
    window.deleteBranch = async (branchName) => {
      if (!confirm(`确定要删除分支 "${branchName}" 吗？`)) {
        return;
      }
      
      const repoPath = repoPathInput.value.trim();
      if (!repoPath) return showMessage(branchListEl, '请先设置仓库路径', true);
      
      try {
        const response = await fetch('/api/delete-branch', {
          method: 'POST',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify({ repoPath, branchName })
        });
        const data = await response.json();
        
        if (data.success) {
          alert(`分支删除成功: ${branchName}`);
          refreshBranches();
        } else {
          alert(`删除分支失败: ${data.error}`);
        }
      } catch (err) {
        alert(`删除分支失败: ${err.message}`);
      }
    };

    // 刷新远程仓库列表
    const refreshRemotes = async () => {
      const repoPath = repoPathInput.value.trim();
      if (!repoPath) return showMessage(remoteListEl, '请先设置仓库路径', true);
      
      try {
        const response = await fetch('/api/remotes', {
          method: 'POST',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify({ repoPath })
        });
        const data = await response.json();
        
        if (data.success) {
          remoteListEl.innerHTML = '';
          
          if (data.remotes && data.remotes.length > 0) {
            data.remotes.forEach(remote => {
              const remoteEl = document.createElement('div');
              remoteEl.className = 'flex justify-between items-center p-1 border rounded text-sm';
              remoteEl.innerHTML = `
                <span class="font-medium">${remote.name}</span>
                <span class="text-gray-500 text-xs">${remote.url}</span>
              `;
              remoteListEl.appendChild(remoteEl);
            });
          } else {
            remoteListEl.innerHTML = '<div class="text-gray-500 text-sm">没有配置远程仓库</div>';
          }
        } else {
          showMessage(remoteListEl, data.error, true);
        }
      } catch (err) {
        showMessage(remoteListEl, '获取远程仓库失败: ' + err.message, true);
      }
    };

    // 刷新远程仓库按钮事件
    refreshRemotesBtn.addEventListener('click', refreshRemotes);

    // 添加远程仓库
    addRemoteBtn.addEventListener('click', async () => {
      const repoPath = repoPathInput.value.trim();
      const name = remoteNameInput.value.trim();
      const url = remoteUrlInput.value.trim();
      
      if (!repoPath) return showMessage(remoteListEl, '请先设置仓库路径', true);
      if (!name) return showMessage(remoteListEl, '请输入远程仓库名称', true);
      if (!url) return showMessage(remoteListEl, '请输入远程仓库URL', true);
      
      try {
        const response = await fetch('/api/add-remote', {
          method: 'POST',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify({ repoPath, name, url })
        });
        const data = await response.json();
        
        if (data.success) {
          alert(`远程仓库添加成功: ${name}`);
          remoteNameInput.value = '';
          remoteUrlInput.value = '';
          refreshRemotes();
        } else {
          alert(`添加远程仓库失败: ${data.error}`);
        }
      } catch (err) {
        alert(`添加远程仓库失败: ${err.message}`);
      }
    });

    // 推送分支
    pushBranchBtn.addEventListener('click', async () => {
      const repoPath = repoPathInput.value.trim();
      if (!repoPath) return showMessage(remoteListEl, '请先设置仓库路径', true);
      
      try {
        const response = await fetch('/api/push', {
          method: 'POST',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify({ repoPath })
        });
        const data = await response.json();
        
        if (data.success) {
          alert(data.message);
        } else {
          alert(`推送失败: ${data.error}`);
        }
      } catch (err) {
        alert(`推送失败: ${err.message}`);
      }
    });
  </script>
</body>
</html>
    